using CMS.Auth;
using CMS.DataAccess;
using CMS.Excep;
using CMS.Model;
using CMS.ServiceProvider;
using CMS.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Newtonsoft.Json.Serialization;
using System.Text.Encodings.Web;
using System.Text.Json.Serialization;
using System.Text.Unicode;
namespace CMS
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            builder.Services.AddControllers();
            builder.Services.AddHttpContextAccessor();
            builder.Services.AddScoped<DbInstance>();
            builder.Services.AddScoped<OptUser>();
            builder.Services.AddScoped<UserServiceProvider>();
            builder.Services.AddScoped<DseClassServiceProvider>();
            builder.Services.AddScoped<CourseServiceProvider>();
            builder.Services.AddScoped<ScheduleServiceProvider>();
            builder.Services.AddScoped<ScheduleTemplateServiceProvider>();
            builder.Services.AddScoped<TimeTableServiceProvider>();
            builder.WebHost.UseUrls("http://*:5000");

            builder.Services.AddControllers(o =>
            {
                o.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
            });
                /*.AddJsonOptions(o =>
            {
                o.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
                o.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
            });*/
            builder.Services.AddMvc(o =>
            {
                o.ValueProviderFactories.Add(new JQueryQueryStringValueProviderFactory());
                o.Filters.Add(typeof(GlobalExceptions));
                o.Filters.Add(typeof(MyTokenGlobalExceptions));
                o.Filters.Add(typeof(MyGlobalExceptions));
            }).AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new MyDefaultContractResolver();
            }); 
            SetupAuthorization(builder);
            var app = builder.Build();
            ServiceLoader.InitHttpServiceProvider(app.Services);
            app.UseAuthorization();
            app.MapControllers();
            app.UseStaticFiles();
            app.Run();
        }
        private static void SetupAuthorization(WebApplicationBuilder builder)
        {
            builder.Services.AddAuthentication(Const.BASE_RULE).AddJwtBearer(Const.BASE_RULE, option =>
            {
                option.TokenValidationParameters = new UserTokenManager().GetTokenValidationParameters();
            });

            builder.Services.AddAuthorization(authorizationOptions =>
            {
                authorizationOptions.AddPolicy(Const.BASE_RULE, policy => policy.AddRequirements(new MyAuthorizationRequirement()));
            });
            builder.Services.AddScoped<IMyFailureReason,MyFailureReason>();
            builder.Services.AddScoped<IAuthorizationHandler, MyAuthorizationHandler>();
            builder.Services.AddScoped<IAuthorizationMiddlewareResultHandler, MyAuthorizationMiddlewareResultHandler>();
        }
    }
}
